<%--
  Created by IntelliJ IDEA.
  User: 联想
  Date: 2020/3/29
  Time: 22:56
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
    <title>jQuery仿电脑蜘蛛纸牌游戏代码</title>
    <meta charset="utf-8" />
    <meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible" />
    <meta content="webkit" name="renderer" />
    <meta content="width=device-width, initial-scale=1" name="viewport" />
    <meta content="Title" name="apple-mobile-web-app-title" />
    <meta content="yes" name="apple-mobile-web-app-capable" />
    <meta content="black" name="apple-mobile-web-app-status-bar-style" />
    <meta content="True" name="HandheldFriendly" />

    <link rel="stylesheet" href="${pageContext.request.contextPath}/static/game03/css/public.css">

    <script src="${pageContext.request.contextPath}/static/game03/js/jquery.min.js"></script>

</head>
<body>

<div class="gameView" id="gameView">
    <div class="gameBg"></div>
    <div class="pokerBox" id="pokerBox"></div>
</div>

<script type="text/javascript">
    $('#pokerBox').on('mousedown','img',function(event){
        event.preventDefault();
    })

    var pickLeft = pickTop = 0;
    var pickObj = null;
    $('body').on('mousedown','#pokerBox .pokerLine .pokerLi',function(event){
        var check = checkCanPickPoker(this);
        if(check.state){
            var e = event || window.event;
            pickLeft = e.offsetX;
            pickTop = e.offsetY;
            pickObj = $(this);

            var groupTop = Number($(this).attr('groupTop'));
            var html = '';
            $(this).closest('.pokerLine').find('.pokerLi').each(function(){
                if($(this).attr('groupTop')>=groupTop){
                    html += $(this).prop('outerHTML');
                    $(this).attr('state','move');
                }
            });

            var itLeft = e.clientX - pickLeft;
            var itTop = e.clientY - pickTop;
            $('#pokerBox .pokerMoveGroup').show().css({
                top: itTop,
                left: itLeft,
            }).html(html);
        }else{
            gAlert({
                txt: '该牌不允许被拖动',
            });
        }
    }).on('mousemove',function(event){
        if(pickObj){
            var e = event || window.event;
            var itLeft = e.clientX - pickLeft;
            var itTop = e.clientY - pickTop;
            $('#pokerBox .pokerMoveGroup').css({
                top: itTop,
                left: itLeft,
            })
        }
    }).on('mouseup',function(event){
        if(pickObj){
            var endLeft = Number($('#pokerBox .pokerMoveGroup').css('left').replace('px',''))+50;
            var leftKb = $('#gameView')[0].offsetLeft;
            var range = 0;
            if(endLeft<=leftKb+120+10){ // 处于第一列
                range = 1;
            }else if(endLeft>=leftKb+120*9+10){ // 处于最后一列
                range = 10;
            }else{
                range = Math.ceil((endLeft-leftKb)/120);
            }

            var moveCard = pickObj;
            var endCard = $('#pokerBox .pokerLine[group="'+range+'"] .pokerLi:last');

            if(endCard.length>0){
                var moveCardSplit = moveCard.attr('card').split('-');
                var endCardSplit = endCard.attr('card').split('-');
                // if(moveCardSplit[0]==endCardSplit[0]&&moveCardSplit[1]==endCardSplit[1]-1){
                if(moveCardSplit[1]==endCardSplit[1]-1){
                    $('#pokerBox .pokerLine[group="'+range+'"]').append($('#pokerBox .pokerMoveGroup').html());
                    $('#pokerBox .pokerLine[group="'+range+'"] .pokerLi').attr({
                        grouptop: function(){ return $(this).index()+1 },
                        groupleft: range,
                    })
                    $('#pokerBox .pokerLine .pokerLi[state="move"]').remove();
                }
            }else{
                $('#pokerBox .pokerLine[group="'+range+'"]').append($('#pokerBox .pokerMoveGroup').html());
                $('#pokerBox .pokerLine[group="'+range+'"] .pokerLi').attr({
                    grouptop: 1,
                    groupleft: range,
                })
                $('#pokerBox .pokerLine .pokerLi[state="move"]').remove();
            }

            $('#pokerBox .pokerLine .pokerLi[state="move"]').removeAttr('state');

            $('#pokerBox .pokerMoveGroup').hide().css({
                top: 0,
                left: 0,
            }).empty();
            pickLeft = pickTop = 0;
            pickObj = null;
        }

        checkNoOpenPoker(); // 检测并翻开没有翻开的扑克
        checkDonePoker(); // 检测是否可以直接收取正确排序的卡牌
    })

    $('#pokerBox').on('click','.pokerDeposit',function(){
        keepSendPoker();
    })

    // 初始化页面布局
    function initView(){
        var html = html2 = '';
        for(var i=1;i<=10;i++){
            html += '<div class="pokerBr" style="left: '+(120*i-100)+'px" group="'+i+'"></div>';
            html2 += '<div class="pokerLine" style="left: '+(120*i-100)+'px" group="'+i+'"></div>';
        }
        var html3 = '<div class="pokerDeposit"></div>'; // 牌堆
        var html4 = '<div class="pokerMoveGroup"></div>'; // 移动牌组
        var html5 = '<div class="pokerDoneGroup"></div>'; // 完成牌组
        $('#pokerBox').html(html+html2+html3+html4+html5);
    }

    // 生成随机扑克牌数组
    var pokerData = {
        type: [ 'a', 'b', 'c', 'd' ], // [a 方片] [b 梅花] [c 黑桃] [d 红桃]
        num: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ],
    };
    var pokerAllCount = 0;
    var pokerAllPet = [];
    var pokerSendNum = 0;
    var pokerDifficult = 1; // [1 简单（单色）] [2 中等（双色）] [3 困难（四色）]
    function initRandomPoker(){
        pokerAllCount = 0;
        pokerAllPet = [];
        pokerSendNum = 0;
        for(var i=1;i<=pokerData.type.length;i++){
            for(var t=1;t<=pokerData.num.length;t++){
                var d = pokerData.type[i-1]+'-'+pokerData.num[t-1];
                pokerAllPet.push(d,d);
            }
        }
        // console.log(pokerAllPet);
        pokerAllCount = pokerAllPet.length;
        pokerAllPet = shuffle(pokerAllPet);
    }

    // 数组随机排序
    function shuffle(arr){
        var len = arr.length;
        for(var i = 0; i < len - 1; i++){
            var idx = Math.floor(Math.random() * (len - i));
            var temp = arr[idx];
            arr[idx] = arr[len - i - 1];
            arr[len - i -1] = temp;
        }
        return arr;
    }

    // 生成扑克牌卡片
    function initPokerCard(){
        var html = '';
        for(var i=1;i<=pokerAllCount;i++){
            var sort = pokerAllCount-i+1;
            var card = pokerAllPet[sort-1];

            // if(sort == 34){
            // 	card = 'a-3'
            // }else if(sort == 44){
            // 	card = 'a-2'
            // }else if(sort == 54){
            // 	card = 'a-1'
            // }

            html += '<div class="pokerLi" isOpen="no" sort="'+sort+'" card="'+card+'" style="left: '+(i*2-1)+'px;">'+
                '<div class="img">'+
                '<img src="${pageContext.request.contextPath}/static/game03/img/'+card+'.png" name="face" />'+
                '<img src="${pageContext.request.contextPath}/static/game03/img/f-1.png" name="back" />'+
                '</div>'+
                '</div>';
        }
        $('#pokerBox .pokerDeposit').append(html);
    }

    // 首次发牌动画
    function initFirstSendPoker(){
        var pokerLineView = 54; // [ 6, 6, 6, 6, 5, 5, 5, 5, 5, 5 ]
        var pokerLineStart = 1;
        var pokerLineInset = null;
        setTimeout(function(){
            pokerLineInset = setInterval(function(){
                var s = pokerLineStart;
                if(s<=54){ // 执行首次发牌
                    var groupTop = Math.ceil(s/10);
                    var top = (groupTop-1)*30;
                    var groupLeft = (s-1)%10+1;
                    var left = (groupLeft-1)*120;
                    animateSendPoker(s,{
                        param: {
                            top: -612+top,
                            left: left,
                            // 'z-index': s,
                        },
                        group: {
                            groupTop: groupTop,
                            groupLeft: groupLeft,
                        },
                    });
                    pokerLineStart++;
                    pokerSendNum++;
                }else{
                    clearInterval(pokerLineInset);
                    setTimeout(function(){
                        for(var i=pokerLineView-9;i<=pokerLineView;i++){ // 执行首次翻牌
                            // for(var i=pokerLineView-54;i<=pokerLineView;i++){ // 执行首次翻牌
                            animateOpenPoker(i);
                        }
                    },200)
                }
            },100)
        },800)
    }

    // 继续发牌
    function keepSendPoker(){
        var canSend = true;
        $('#pokerBox .pokerLine').each(function(){
            if($(this).find('.pokerLi').length==0){
                canSend = false;
            }
        })
        if(canSend){
            var lastAllNum = pokerSendNum;
            var pokerLineStart = lastAllNum+1;
            var pokerLineInset = null;
            pokerLineInset = setInterval(function(){
                var s = pokerLineStart;
                if(s<=lastAllNum+10){ // 每轮发牌10张
                    var groupLeft = s-lastAllNum;
                    var left = (groupLeft-1)*120;
                    var groupTop = $('#pokerBox .pokerLine[group="'+groupLeft+'"] .pokerLi').length+1;
                    var top = (groupTop-1)*30;
                    animateSendPoker(s,{
                        param: {
                            top: -612+top,
                            left: left,
                            // 'z-index': s,
                        },
                        group: {
                            groupTop: groupTop,
                            groupLeft: groupLeft,
                        },
                    },function(){
                        animateOpenPoker(s);
                    });
                    pokerLineStart++;
                    pokerSendNum++;
                }else{
                    clearInterval(pokerLineInset);
                }
            },100)
        }else{
            gAlert({
                txt: '不允许在有空列的时候发牌',
            })
        }
    }

    // 执行发牌动画 [s 序号] [j 参数] [c 回调函数]
    function animateSendPoker(s,j,c){
        var obj = $('#pokerBox .pokerDeposit .pokerLi[sort="'+s+'"]');
        obj.attr(j.group).animate(j.param,150,function(){
            $('#pokerBox .pokerLine[group="'+j.group.groupLeft+'"]').append(obj.addClass('importantClass').prop('outerHTML'));
            obj.remove();
            if(c){ c(); }
        });
    }

    // 执行翻牌动画 [s 序号] [j 参数] [c 回调函数]
    function animateOpenPoker(s,j,c){
        $('#pokerBox .pokerLine .pokerLi[sort="'+s+'"]').attr('isOpen','yes');
    }

    // 检测是否可以拖动
    function checkCanPickPoker(obj){
        var result = {
            state: false, // 是否可以拖动 [true 可以] [false 不可以]
            dropGroupTop: 0, // 拖动的卡牌序号
        }
        if($(obj).attr('isOpen')=='yes'){
            var groupTop = Number($(obj).attr('groupTop'));
            var groupCardArr = [];
            $(obj).closest('.pokerLine').find('.pokerLi').each(function(){
                if($(this).attr('groupTop')>=groupTop){
                    var c = $(this).attr('card').split('-');
                    groupCardArr.push({
                        a: c[0],
                        b: Number(c[1]),
                        g: $(this).attr('groupTop'),
                    });
                }
            })
            // console.log(groupCardArr);

            result.state = true;
            result.dropGroupTop = groupCardArr[0].g;

            if(groupCardArr.length>1){
                for(var i=0;i<=groupCardArr.length-2;i++){
                    var nowCard = groupCardArr[i];
                    var nextCard = groupCardArr[i+1];
                    if( !(nowCard.a==nextCard.a && nowCard.b==nextCard.b+1) ){
                        result.state = false;
                        result.dropGroupTop = 0;
                    }
                }
            }
        }
        return result;
    }

    // 检测并翻开没有翻开的扑克
    function checkNoOpenPoker(){
        if(pokerSendNum<54){ return false; }
        $('#pokerBox .pokerLine').each(function(){
            if($(this).find('.pokerLi:last').attr('isOpen')=='no'){
                $(this).find('.pokerLi:last').attr('isOpen','yes');
            }
        })
    }

    // 检测是否可以直接收取正确排序的卡牌
    function checkDonePoker(){
        if(pokerSendNum<54){ return false; }
        $('#pokerBox .pokerLine .pokerLi[isopen="yes"][card$="-13"]').each(function(){
            var checkBit = $(this).attr('card').split('-')[0];
            var checkTop = Number($(this).attr('groupTop'));
            var pobj = $(this).closest('.pokerLine');
            var isDone = true;
            var pushCard = [ $(this).attr('sort') ];
            for(var i=1;i<=12;i++){
                var s = pobj.find('.pokerLi[isopen="yes"][groupTop="'+(checkTop+i)+'"]');
                pushCard.push(s.attr('sort'));
                if(pobj.find('.pokerLi[isopen="yes"][groupTop="'+(checkTop+i)+'"]').attr('card')!=checkBit+'-'+(13-i)){
                    isDone = false;
                    break;
                }
            }
            if(isDone){
                pushCard.reverse();
                moveDonePoker(pushCard);
            }
        })
    }

    // 收起正确排序的卡牌
    function moveDonePoker(arr){
        var endTop = $('#pokerBox .pokerDoneGroup').offset().top;
        var endLeft = $('#pokerBox .pokerDoneGroup').offset().left;
        var html = '';
        $.each(arr, function(a,b){
            var s = $('#pokerBox .pokerLine .pokerLi[sort="'+b+'"]');
            var top = s.offset().top;
            var left = s.offset().left;
            s.removeClass('importantClass').css({
                'position': 'fixed',
                'left': left,
                'top': top,
            });
            html += s.prop('outerHTML');
            s.animate({ top: endTop, left: endLeft },250,function(){
                s.remove();
                if(a==arr.length-1){
                    $('#pokerBox .pokerDoneGroup').append(html);
                }
            });
        });
    }

    // 弹框
    function gAlert(json){
        var json = $.extend({
            txt: '',
            txtCenter: false,
            btn: '',
            btnCall: null,
            btn2: '',
            btn2Call: null,
            btn3: '',
            btn3Call: null,
        },json)
        // console.log(json);

        var hasBtn = hasBtn2 = hasBtn3 = false;
        if(json.btn&&json.btn!=''){ hasBtn = true; }
        if(json.btn2&&json.btn2!=''){ hasBtn2 = true; }
        if(json.btn3&&json.btn3!=''){ hasBtn3 = true; }

        var html = '<div class="gAlert" state="now">'+
            '<div class="txt" style="'+(json.txtCenter?'text-align:center;':'')+'">'+json.txt+'</div>'+
            (hasBtn||hasBtn2||hasBtn3?
                '<div class="tool disFlex heiAuto widAuto">'+
                (hasBtn?'<div class="btn btn1">'+json.btn+'</div>':'')+
                (hasBtn2?'<div class="btn btn2">'+json.btn2+'</div>':'')+
                (hasBtn3?'<div class="btn btn3">'+json.btn3+'</div>':'')+
                '</div>'
                :'')+
            '</div>';
        $('.gAlert:not(.out)').addClass('out').attr('state','out');
        $('body').append(html);
        var sobj =  $('.gAlert[state="now"]');
        sobj.find('.btn').click(function(){
            sobj.addClass('out').attr('state','out');
            if($(this).hasClass('btn1')&&json.btnCall){
                json.btnCall();
            }else if($(this).hasClass('btn2')&&json.btn2Call){
                json.btn2Call();
            }else if($(this).hasClass('btn3')&&json.btn3Call){
                json.btn3Call();
            }
        })

        if(!hasBtn&&!hasBtn2&&!hasBtn3){
            sobj.css('width','auto');
            var width = sobj.outerWidth();
            sobj.css({'margin-left': -width/2});
            setTimeout(function(){
                sobj.addClass('out').attr('state','out');
            },2000)
        }

        setTimeout(function(){
            sobj.css('top',30);
        },200)
    }

    // 选择游戏难度
    function chooseGameDifficulty(){
        gAlert({
            txt: '请选择游戏难度',
            txtCenter: true,
            btn: '简单（单色）',
            btnCall: function(){
                pokerDifficult = 1;
                pokerData.type = [ 'c', 'c', 'c', 'c' ];
                initGame();
            },
            btn2: '中等（双色）',
            btn2Call: function(){
                pokerDifficult = 2;
                pokerData.type = [ 'c', 'd', 'c', 'd' ];
                initGame();
            },
            btn3: '困难（四色）',
            btn3Call: function(){
                pokerDifficult = 3;
                pokerData.type = [ 'a', 'b', 'c', 'd' ];
                initGame();
            },
        });
    }

    // 开始游戏
    function initGame(){
        initRandomPoker(); // 生成随机扑克牌数组
        initPokerCard(); // 生成扑克牌卡片
        initFirstSendPoker(); // 触发首次发牌动画
    }

    initView(); // 初始化页面布局
    chooseGameDifficulty(); // 选择游戏难度
</script>

</body>
</html>
